#include "HTTP_Demo.h"
#include "ui_HTTP_Demo.h"
#include <QFileDialog>
#include <QMessageBox>

#define TIME_INTERVAL 300

HTTP_Demo::HTTP_Demo(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::HTTP_Demo)
{
    ui->setupUi(this);
}

HTTP_Demo::~HTTP_Demo()
{
    delete ui;
}


void HTTP_Demo::on_pushButton_defaultPath_clicked()
{
    //缺省路径按钮
    QString curPath="C:/Users/Administrator/Downloads";
    QDir dir (curPath) ;
    QString sub="temp";
    dir.mkdir (sub) ;
    ui->lineEdit_fileSavePath->setText (curPath+"/"+sub+"/") ;
}

void HTTP_Demo::on_pushButton_selectFilePath_clicked()
{
    QString selectdir = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
                                                          "/home",
                                                          QFileDialog::ShowDirsOnly
                                                          | QFileDialog::DontResolveSymlinks);
    QDir dir (selectdir) ;
    QString sub="temp";
    dir.mkdir (sub) ;
    ui->lineEdit_fileSavePath->setText(selectdir+"/"+sub+"/");
}

QString HTTP_Demo::timeFormat(qint64  seconds)
{
    QString strValue;
    QString strSpacing(" ");
    if (seconds <= 0)
    {
        strValue = QString("%1s").arg(0);
    }
    else if (seconds < 60)
    {
        strValue = QString("%1s").arg(seconds);
    }
    else if (seconds < 60 * 60)
    {
        int nMinute = seconds / 60;
        int nSecond = seconds - nMinute * 60;

        strValue = QString("%1m").arg(nMinute);

        if (nSecond > 0)
            strValue += strSpacing + QString("%1s").arg(nSecond);
    }
    else if (seconds < 60 * 60 * 24)
    {
        int nHour = seconds / (60 * 60);
        int nMinute = (seconds - nHour * 60 * 60) / 60;
        int nSecond = seconds - nHour * 60 * 60 - nMinute * 60;

        strValue = QString("%1h").arg(nHour);

        if (nMinute > 0)
            strValue += strSpacing + QString("%1m").arg(nMinute);

        if (nSecond > 0)
            strValue += strSpacing + QString("%1s").arg(nSecond);
    }
    else
    {
        int nDay = seconds / (60 * 60 * 24);
        int nHour = (seconds - nDay * 60 * 60 * 24) / (60 * 60);
        int nMinute = (seconds - nDay * 60 * 60 * 24 - nHour * 60 * 60) / 60;
        int nSecond = seconds - nDay * 60 * 60 * 24 - nHour * 60 * 60 - nMinute * 60;

        strValue = QString("%1d").arg(nDay);

        if (nHour > 0)
            strValue += strSpacing + QString("%1h").arg(nHour);

        if (nMinute > 0)
            strValue += strSpacing + QString("%1m").arg(nMinute);

        if (nSecond > 0)
            strValue += strSpacing + QString("%1s").arg(nSecond);
    }

    return strValue;
}
QString HTTP_Demo::speed(double speed)
{
    QString strUnit;
    if (speed <= 0)
    {
        speed = 0;
        strUnit = "Bytes/S";
    }
    else if (speed < 1024)
    {
        strUnit = "Bytes/S";
    }
    else if (speed < 1024 * 1024)
    {
        speed /= 1024;
        strUnit = "KB/S";
    }
    else if (speed < 1024 * 1024 * 1024)
    {
        speed /= (1024 * 1024);
        strUnit = "MB/S";
    }
    else
    {
        speed /= (1024 * 1024 * 1024);
        strUnit = "GB/S";
    }

    QString strSpeed = QString::number(speed, 'f', 2);
    return QString("%1 %2").arg(strSpeed).arg(strUnit);
}

QString HTTP_Demo::size(qint64 bytes)
{
    QString strUnit;
    double dSize = bytes * 1.0;
    if (dSize <= 0)
    {
        dSize = 0.0;
    }
    else if (dSize < 1024)
    {
        strUnit = "Bytes";
    }
    else if (dSize < 1024 * 1024)
    {
        dSize /= 1024;
        strUnit = "KB";
    }
    else if (dSize < 1024 * 1024 * 1024)
    {
        dSize /= (1024 * 1024);
        strUnit = "MB";
    }
    else
    {
        dSize /= (1024 * 1024 * 1024);
        strUnit = "GB";
    }

    return QString("%1 %2").arg(QString::number(dSize, 'f', 2)).arg(strUnit);
}
void HTTP_Demo::on_pushButton_download_clicked()
{
    if(m_isStop)
    {
        m_isStop = false;
        //开始下载
        QString urlSpec = ui->lineEdit_downloadURL->text ().trimmed() ;
        if (urlSpec. isEmpty() )
        {
            QMessageBox::information(this, "错误","请指定需要下载的URL") ;
            m_isStop = true;
            return;
        }
        bool isHttpsRequest;
        //不区分大小写
        if(urlSpec.startsWith("https:", Qt::CaseInsensitive))
        {
            isHttpsRequest = true;
        }

        QUrl newUrl = QUrl(urlSpec) ;
        if ( !newUrl. isValid() )
        {
            QMessageBox:: information(this,"错误",QString("无效URL: 81 \n错误信息: 82") .arg (urlSpec, newUrl.errorString())) ;
            m_isStop = true;
            return;
        }
        QString tempDir =ui->lineEdit_fileSavePath->text().trimmed() ;
        if (tempDir. isEmpty())
        {
            QMessageBox::information(this, "错误", "请指定保存下载文件的目录") ;
            m_isStop = true;
            return;
        }

        QString fileName = newUrl.fileName ();

        //如果找不到文件名称，就默认写一个
        if(fileName.isEmpty())
        {
            fileName = "temp.date";
        }
        QString fullFileName =tempDir+fileName ;

        // 如果当前下载的字节数为0那么说明未下载过或者重新下载
        // 则需要检测本地是否存在之前下载的临时文件，如果有则删除
        if (m_bytesCurrentReceived <= 0)
        {
            m_ReplyData.clear();
            QFile::remove(fullFileName);
        }
        else if (QFile::exists (fullFileName))
        {
            QFile::remove(fullFileName) ;
        }
        m_fileName = fullFileName;

        ui->pushButton_download->setEnabled(false) ;
        if(mNetworkManager == nullptr)
        {
            mNetworkManager = new QNetworkAccessManager(this);
        }

        QNetworkRequest request2(newUrl);

        // 如果支持断点续传，则设置请求头信息
        if (m_isSupportBreakPoint)
        {
            qInfo()<<"进入断点续传";
            QString strRange = QString("bytes=%1-").arg(m_bytesCurrentReceived);
            request2.setRawHeader("Range", strRange.toLatin1());
        }

        mPReply = mNetworkManager->get(request2);

        connect (mPReply, &QNetworkReply::finished,  this, &HTTP_Demo::onFinish) ;
        connect (mPReply, &QNetworkReply::readyRead, this, &HTTP_Demo::onReadyRead) ;
        connect (mPReply, &QNetworkReply::downloadProgress,  this, &HTTP_Demo::onDownloadProgress) ;

        m_timeInterval = 0;
        m_timeRecord.start();
    }
}

void HTTP_Demo::onFinish()
{
    mPReply->deleteLater() ;
    mPReply = nullptr;
    QFile file(m_fileName);
    if(file.open(QIODevice::WriteOnly))
    {
        file.write(m_ReplyData);
    }

    file.close();

    ui ->pushButton_download->setEnabled(true) ;
}

void HTTP_Demo::onReadyRead()
{
    if(!m_isStop)
    {
         m_ReplyData += mPReply->readAll();
    }
}

void HTTP_Demo::onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
    m_bytesReceived = bytesReceived;
    m_bytesTotal = bytesTotal;
   // qInfo()<<"进度进来"<<bytesReceived;
    qInfo()<<"onDownloadProgress total "<<bytesTotal;
    //下载进程,设置最大值为100
    ui->progressBar->setMinimum(0);
    ui->progressBar->setMaximum(100) ;

    calculateDownloadProgress(m_bytesReceived+m_bytesCurrentReceived, m_bytesTotal + m_bytesCurrentReceived);
}

void HTTP_Demo::calculateDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{

    //计算您当前的进度
    float currentProgressValue = static_cast<float>(bytesReceived)/static_cast<float>(bytesTotal)*100;
    qInfo()<<"currentProgressValue"<<currentProgressValue ;

    ui->progressBar-> setValue (currentProgressValue) ;

    // 输出当前下载进度;
    // 用到除法需要注意除0错误;
    //qDebug() << QString("%1").arg(bytesReceived * 100 / bytesTotal + 1);


    // m_intervalDownload 为下次计算速度之前的下载字节数;
    m_intervalDownloadSize += bytesReceived - m_currentDownloadSize;
    m_currentDownloadSize = bytesReceived;

    int timeNow = m_timeRecord.elapsed();

    // 超过0.3s更新计算一次速度;
    if (timeNow - m_timeInterval > TIME_INTERVAL)
    {
        qint64 ispeed = m_intervalDownloadSize * 1000 / (timeNow - m_timeInterval);
        QString strSpeed = speed(ispeed);
        ui->label_speed->setText("当前下载速度:"+strSpeed);

        // 剩余时间;
        qint64 timeRemain = 0;
        if (ispeed != 0)
        {
            timeRemain = (bytesTotal - bytesReceived) / ispeed;
        }

        //转换单位(下载剩余时间)
        QString strTimeRemain = timeFormat(timeRemain);

        ui->label_time->setText("剩余时间:"+strTimeRemain);
        //当前已下载的数据大小
        QString currentFileDownSize = size(m_currentDownloadSize);

        ui->label_downSize->setText("已下载大小:"+currentFileDownSize);

        //下载文件的总大小
        QString totalFileSize = size(bytesTotal);
        ui->label_totalSize->setText("文件总大小:"+totalFileSize);

        m_intervalDownloadSize = 0;
        m_timeInterval = timeNow;

    }
}


void HTTP_Demo::on_pushButton_pause_clicked()
{
    // 这里m_isStop变量为了保护多次点击暂停下载按钮，导致m_bytesCurrentReceived 被不停累加;
    if (!m_isStop)
    {
        //记录当前已经下载字节数
        m_bytesCurrentReceived += m_bytesReceived;
        stopWork();
    }
}

// 停止下载工作;
void HTTP_Demo::stopWork()
{
    m_isStop = true;
    if (mPReply != nullptr)
    {
        disconnect (mPReply, &QNetworkReply::finished,  this, &HTTP_Demo::onFinish) ;
        disconnect (mPReply, &QNetworkReply::readyRead, this, &HTTP_Demo::onReadyRead) ;
        disconnect (mPReply, &QNetworkReply::downloadProgress,  this, &HTTP_Demo::onDownloadProgress) ;
        mPReply->abort();
        mPReply->deleteLater();
        mPReply = nullptr;
    }
}
void HTTP_Demo::on_pushButton_start_clicked()
{
    on_pushButton_download_clicked();
}
